/*
 * Solution.cpp
 *
 *  Created on: Sep 19, 2012
 *      Author: pedro
 */

#include "Solution.h"

Solution::Solution() {
	nCycles = 0;
	cost = 0;
}


Solution::Solution(vector<int> &input) {
	answer.assign(input.begin(), input.end());

	cycles.resize(input.size());

	nCycles = 0;
	cost = 0;

	processCycles();
}

Solution::~Solution() {

}

vector<int> Solution::getAnswer()
{
	return answer;
}

bool Solution::isGood() {
	if (nCycles == 1)
		return true;
	return false;
}

int Solution::getNCycles() {
	return nCycles;
}

Index Solution::getCycleEdge(Problem &p, int *cycleInf) {
	int cycleSize = 0;
	Index point(0, 0);

	for (int i = 0; i < nCycles; ++i)
	{

		for (unsigned int j = 0; j < (cycles[i]).size() - 1; ++j)
		{
			int from = cycles[i][j];
			int to = cycles[i][j + 1];

			if (p.getConstraints()(from, to) != AVALIABLE)
				cycleSize++;
			else
			{
				point.setX(from);
				point.setY(to);
			}

		}

		//se existe pelo menos uma aresta não selecionada no ciclo
		if (cycleSize < (int) (cycles[i]).size() - 2)
			*cycleInf = NO_CYCLE;
		else
			*cycleInf = CYCLE;

		if (!(point.getX() == 0 && point.getY() == 0))
			return point;

		cycleSize = 0;
	}

	return point;
}

void Solution::printSolution() {
	for (unsigned int i = 0; i < answer.size(); ++i)
		cout << answer[i] << " ";
}

void Solution::calculateCost(Graph &graph) {
	cost = 0;
	for (int i = 0; i < graph.getSize(); ++i)
		cost += graph(i, answer[i]);
}

int Solution::getCost() {
	return cost;
}

bool Solution::hasCost() {
	if (cost == 0)
		return false;
	return true;
}

void Solution::processCycles() {
	int size = answer.size();
	int *auxiliar = new int[size];
	int found = 0;
	int i = 0;
	int position = 0;

	for (int i = 0; i < size; ++i)
	{
		auxiliar[i] = NOT_FOUND;
	}

	while (found < size)
	{
		if (auxiliar[i] == NOT_FOUND)
		{
			auxiliar[i] = FOUND;
			cycles[nCycles].push_back(i);
			position++;
			i = answer[i];
			found++;
		} else if (auxiliar[i] == FOUND && position != 0)
		{
			cycles[nCycles].push_back(i);
			nCycles++;
			i = 0;
			position = 0;
		} else
			i++;
	}

	cycles[nCycles].push_back(i);
	nCycles++;

	delete[] auxiliar;
}

void Solution::build(vector<int> &input)
{
	answer.assign(input.begin(), input.end());

	cycles.resize(input.size());

	nCycles = 0;
	cost = 0;

	processCycles();
}
